package com.xinlong.shop.generator.config;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.xinlong.shop.generator.model.GeneratorVO;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author Sylow
 * @Description 代码生成器配置
 * @Date: Created in 17:20 2022/6/12
 */
@Component
public class GeneratorConfig {

    private final DbConfig dbConfig;

    public GeneratorConfig(DbConfig dbConfig) {
        this.dbConfig = dbConfig;
    }

    /**
     * 初始化全局配置
     * @return
     */
    private GlobalConfig.Builder globalConfig(String author) {
        GlobalConfig.Builder globalConfig = new GlobalConfig.Builder();

        // 生成路径
        String tmpdir = "/Users/Sylow/opt/code";
        //String tmpdir = System.getProperty("java.io.tmpdir") + "xinlong-code." + IdWorker.getIdStr();

        // 作者
        globalConfig.author(author)
                    .outputDir(tmpdir)
                    .disableOpenDir();   // 禁止打开输出目录
        //globalConfig.enableSwagger();
        return globalConfig;
    }

    /**
     * 初始化数据源配置
     * @return
     */
    private DataSourceConfig dataSourceConfig() {
        return new DataSourceConfig.Builder(dbConfig.getUrl(), dbConfig.getUserName(), dbConfig.getPassword()).build();
    }

    /**
     * 初始化策略
     * @param tables 数据表
     * @return
     */
    private StrategyConfig.Builder strategyConfig(List<String> tables) {
        StrategyConfig.Builder strategyConfig = new StrategyConfig.Builder().addInclude(tables).addTablePrefix("s_", "sys_");
        strategyConfig.entityBuilder().formatFileName("%s")
                .mapperBuilder().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper")
                .controllerBuilder().enableRestStyle().formatFileName("%sController")
                .serviceBuilder().formatServiceFileName("I%sService").formatServiceImplFileName("%sServiceImpl");
                //逻辑删除字段 和 默认乐观锁字段
                //.entityBuilder().logicDeleteColumnName(deleteColumn).versionColumnName(versionColumn);

        return strategyConfig;
    }

    /**
     * 包配置
     * @param packageName
     * @param moduleName
     * @return
     */
    private PackageConfig.Builder packageConfig(String packageName, String moduleName) {
        PackageConfig.Builder packageConfig = new PackageConfig.Builder();
        Map<OutputFile, String> pathInfos = new HashMap<OutputFile, String>();
        pathInfos.put(OutputFile.other, "/Users/Sylow/opt/code/vue");
        pathInfos.put(OutputFile.xml, "/Users/Sylow/opt/code/mapper");

        packageConfig.parent(packageName)
                //父包模块名
                .moduleName(moduleName)
                .pathInfo(pathInfos);
        return packageConfig;
    }

    /**
     * 模板配置
     * @return
     */
    private TemplateConfig.Builder templateConfig() {
        TemplateConfig.Builder templateConfig = new TemplateConfig.Builder();
        templateConfig.serviceImpl("/code_template/serviceImpl.java")
                        .controller("/code_template/controller.java")
                        .entity("/code_template/entity.java")
                        .mapper("/code_template/mapper.java")
                        .xml("/code_template/mapper.xml")
                        .service("/code_template/service.java");
        return templateConfig;
    }

    private InjectionConfig.Builder injectionConfig(String moduleName){
        InjectionConfig.Builder injectionConfig = new InjectionConfig.Builder();
        Map<String, String> customFiles = new HashMap<>();
        customFiles.put("api.ts", "/code_template/api.ts.ftl"); // 前端 api ts
        customFiles.put("columns.ts", "/code_template/columns.ts.ftl"); // 前端 表格ts
        customFiles.put("index.vue", "/code_template/index.vue.ftl"); // 前端 vue页面文件
        injectionConfig
                .customMap(Collections.singletonMap("moduleName", moduleName))
                .customFile(customFiles);
        return injectionConfig;
    }


//
    public void execute(GeneratorVO generatorVO) {
        AutoGenerator generator = new AutoGenerator(dataSourceConfig());
        generator.strategy(strategyConfig(generatorVO.getTables()).build());
        generator.template(templateConfig()
                .build());
        generator.global(globalConfig(generatorVO.getAuthor()).build());
        generator.packageInfo(packageConfig(generatorVO.getPackageConfig(), generatorVO.getModule()).build());
        generator.injection(injectionConfig(generatorVO.getModule()).build());
        generator.execute(new FreemarkerTemplateEngine());
    }
}
